package Controller

import (
	"log"
	"math"
	"math/rand"
	"strconv"
	"time"
	"web_back_go/Common"
	"web_back_go/DAO/gorm"
	"web_back_go/Dto"
	"web_back_go/Response"

	"github.com/gin-gonic/gin"
)

/*
getListResponseEntity

	@Description: 打乱切片元素顺序
	@Parameters({
	          @Parameter(name = "number", description = "取数", required = true),
	          @Parameter(name = "sort", description = "是否按照顺序(0 否 1是)"),
	          @Parameter(name = "list", description = "切片", required = true),
	  })
	@return: []HotSearchDto
*/
func getListResponseEntity(number int, sort int, list interface{}) interface{} {
	switch v := list.(type) {
	case []Dto.HotSearchDto:
		if sort == 0 {
			// 使用局部随机数生成器
			source := rand.NewSource(time.Now().UnixNano())
			r := rand.New(source)
			for i := range v {
				j := r.Intn(len(v))
				v[i], v[j] = v[j], v[i]
			}
		}
		if len(v) == 0 || len(v) < number {
			return v
		}
		return v[:number]
	default:
		return list
	}
}

/*
GetHotSearchByShopId
@Description: 获取店铺的热搜

	@Parameters({
	          @Parameter(name = "shopId", description = "店铺id", required = true),
	          @Parameter(name = "number", description = "取数", required = true),
	          @Parameter(name = "sort", description = "是否按照顺序(0 否 1是)"),
	  })
*/
func GetHotSearchByShopId(c *gin.Context) {
	shopId := c.Query("shopId")
	numberstr := c.Query("number")
	sort := c.Query("sort")

	number, _ := strconv.Atoi(numberstr)
	sortInt, _ := strconv.Atoi(sort)
	db := gorm.Db
	var hotSearchList []Dto.HotSearchDto
	/*
	   SELECT
	   hot_search_id,
	   content,
	   title
	   FROM
	       tz_hot_search
	   WHERE
	       shop_id = #{shopId}
	       AND `status` = 1
	   ORDER BY
	       seq
	*/
	result := db.Table("tz_hot_search").
		Select("hot_search_id, content, title").
		Where("shop_id =? AND `status` = 1", shopId).
		Order("seq").
		Limit(number).
		Find(&hotSearchList)

	if result.Error != nil {
		// 处理查询出错的情况，这里简单返回一个包含错误信息的响应，实际中可根据需求完善错误处理逻辑
		c.JSON(200, Response.ResponseBody{
			Code:      "A0001",
			Msg:       "查询失败",
			Data:      nil,
			Version:   "V1.0.0",
			Timestamp: time.Now().Unix(),
			Sign:      nil,
			Success:   false,
			Fail:      true,
		})
		return
	}

	processedList := getListResponseEntity(number, sortInt, hotSearchList)

	c.JSON(200, Response.ResponseBody{
		Code:      "00000",
		Msg:       nil,
		Data:      processedList,
		Version:   "V1.0.0",
		Timestamp: time.Now().Unix(),
		Sign:      nil,
		Success:   true,
	})
}

/*
GetHotSearchAll
@Description: 获取所有的热搜

	@Parameters({
	            @Parameter(name = "number", description = "取数" , required = true),
	            @Parameter(name = "sort", description = "是否按照顺序(0 否 1是)", required = false ),
	    })
*/
func GetHotSearchAll(c *gin.Context) {
	numberstr := c.Query("number")
	sort := c.Query("sort")
	number, _ := strconv.Atoi(numberstr)
	sortInt, _ := strconv.Atoi(sort)
	db := gorm.Db
	var hotSearchList []Dto.HotSearchDto
	result := db.Table("tz_hot_search").
		Select("hot_search_id, content, title").
		Where("shop_id =? AND `status` = 1", 0).
		Order("seq").
		Limit(number).
		Find(&hotSearchList)
	if result.Error != nil {
		// 处理查询出错的情况，这里简单返回一个包含错误信息的响应，实际中可根据需求完善错误处理逻辑
		c.JSON(200, Response.ResponseBody{
			Code:      "A0001",
			Msg:       "查询失败",
			Data:      nil,
			Version:   "V1.0.0",
			Timestamp: time.Now().Unix(),
			Sign:      nil,
			Success:   false,
			Fail:      true,
		})
		return
	}

	processedList := getListResponseEntity(number, sortInt, hotSearchList)

	c.JSON(200, Response.ResponseBody{
		Code:      "00000",
		Msg:       nil,
		Data:      processedList,
		Version:   "V1.0.0",
		Timestamp: time.Now().Unix(),
		Sign:      nil,
		Success:   true,
	})
}

/*
GetSearchProdPage

	@Description: 搜索商品
	@Parameters({
	        @Parameter(name = "prodName", description = "商品名" , required = true),
	        @Parameter(name = "sort", description = "排序(0 默认排序 1销量排序 2价格排序)"),
	        @Parameter(name = "orderBy", description = "排序(0升序 1降序)"),
	        @Parameter(name = "shopId", description = "店铺id" , required = true),
	})
*/
func GetSearchProdPage(c *gin.Context) {
	prodName := c.Query("prodName")
	currentStr := c.Query("current")
	sizeStr := c.Query("size")
	sort := c.Query("sort")
	orderBy := c.Query("orderBy")
	sortInt, _ := strconv.Atoi(sort)
	orderByInt, _ := strconv.Atoi(orderBy)
	page, err := strconv.Atoi(currentStr)
	var count int64
	if err != nil || page < 1 {
		page = 1
	}

	size, err := strconv.Atoi(sizeStr)
	if err != nil || size < 1 {
		size = 10
	}

	db := gorm.Db

	var orderClause string
	switch sortInt {
	case 1:
		orderClause = "p.sold_num"
	case 2:
		orderClause = "p.price"
	default:
		orderClause = "p.update_time"
	}

	if orderByInt == 1 {
		orderClause += " desc"
	} else {
		orderClause += " asc"
	}

	var prodList []SearchProdDto
	result := db.Table("tz_prod p").
		Select("p.prod_id, p.pic, p.prod_name, p.price, count(pc.prod_comm_id) as prod_comm_number, count( CASE WHEN evaluate = 0 THEN prod_comm_id ELSE null END ) AS praise_number").
		Joins("left join tz_prod_comm pc on p.prod_id=pc.prod_id and pc.`status`=1").
		Where("prod_name like ?", "%"+prodName+"%").
		Group("p.prod_id").
		Order(orderClause).
		Offset((page - 1) * size).
		Limit(size).
		Find(&prodList)
	if result.Error != nil {
		log.Println(result.Error)
		c.JSON(200, Response.ResponseBody{
			Code:    "A00001",
			Msg:     "服务器异常",
			Data:    nil,
			Version: "1.0.0",
		})
		return
	}

	// 计算总数
	db.Table("tz_prod p").
		Select("count(p.prod_id)").
		Joins("left join tz_prod_comm pc on p.prod_id=pc.prod_id and pc.`status`=1").
		Where("prod_name like ?", "%"+prodName+"%").
		Count(&count)
	c.JSON(200, Response.ResponseBody{
		Code: "00000",
		Msg:  nil,
		Data: Common.PageParam1[SearchProdDto]{
			Current: page,
			Total:   count,
			Size:    size,
			Records: getListResponseEntity(size, 0, prodList), // 这里假设不需要再次排序，如果需要可以调整
			Pages:   int(math.Ceil(float64(count) / float64(size))),
		},
		Version:   "V1.0.0",
		Timestamp: time.Now().Unix(),
		Sign:      nil,
		Success:   true,
	})
}

type SearchProdDto struct {
	ProdId         int64   `json:"prodId"`
	Pic            string  `json:"pic"`
	ProdName       string  `json:"prodName"`
	Price          float64 `json:"price"`
	ProdCommNumber int     `json:"prodCommNumber"`
	PositiveRating float64 `json:"positiveRating"`
	PraiseNumber   int     `json:"praiseNumber"`
}
